package org.myrpc.server;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.net.Socket;

import org.myrpc.rpc.RpcServerFactory;
import org.myrpc.rpc.RpcRequest;
import org.myrpc.rpc.RpcResponse;
import org.myrpc.rpc.rpc;
import org.myrpc.utils.AopTargetUtils;
import org.myrpc.utils.CloseUtils;

import com.caucho.hessian.io.HessianInput;
import com.caucho.hessian.io.HessianOutput;

public class RpcServiceRunable implements Runnable{
	private Socket client;

	public RpcServiceRunable(Socket client) {
		this.client = client;
	}

	@Override
	public void run() {
		InputStream in =null;
		HessianInput hessianInput = null;//比普通输入流快一些
		OutputStream out = null;
		HessianOutput hessianOutput = null;
		RpcResponse response = new RpcResponse();
		try {
			//获取请求对象
			in = client.getInputStream();
			hessianInput = new HessianInput(in);
			 
			//准备相应流和序列化
			out = client.getOutputStream();
			hessianOutput = new HessianOutput(out);
			
			//获取请求信息
			Object parm = hessianInput.readObject();
			if(!(parm instanceof RpcRequest)) {//请求非法
				response.setError(new Exception("请求非法"));
				hessianOutput.writeObject(response);
				return;
			}
			RpcRequest request = (RpcRequest) parm;
			
			/*根据接口获取实现类*/
			String className = request.getClassName();
			Class<?> inter = Class.forName(className);
			Object service = RpcServerFactory.getBeanImpl(inter);
			
			if(service==null) {
				response.setError(new Exception("没有相应实现类"));
				hessianOutput.writeObject(response);
				return;
			}
			
			//从动态代理中获取真实的对象
			service = AopTargetUtils.getTarget(service);
			
			Class clazz = service.getClass();
			
			//判断服务
			if(!clazz.isAnnotationPresent(rpc.class)) {
				response.setError(new Exception(clazz.getName()+"没有提供服务"));
				hessianOutput.writeObject(response);
				return;
			}
			
			//找到具体执行方法
			Method method =clazz.getMethod(request.getMethodName(),request.getParamTypes());
			if(method==null) {
				response.setError(new Exception(clazz.getName()+"没有相应的方法"));
				hessianOutput.writeObject(response);
				return;
			}
			
			//执行方法
			Object result = method.invoke(service, request.getParams());
			
			//响应结果
			response.setResult(result);
			hessianOutput.writeObject(response);
		}catch (Exception e) {
			e.printStackTrace();
            // 服务器如果发生异常，响应客户端异常信息      
			if (hessianOutput != null) {              
				response.setError(e);               
				try {                  
					hessianOutput.writeObject(response);            
					} catch (IOException ex) {                 
						ex.printStackTrace();              
					}          
				}
		} finally {         
			CloseUtils.close(in, hessianInput, out, hessianOutput);   
			}
		}
}

